#ifndef IGSLIB_IPACKET_H
#define IGSLIB_IPACKET_H

#include <vector>
#include "igslib_common_use.h"

namespace igslib
{
    /*!
     * 此物件用於多種通訊管道下的通用封包。
     * 不僅與通道無關，也和專案規格無關。
     */
	struct IPacket:public IComponent
	{
        /*!
         * 取得此封包的標頭編號。
         * @return 此封包的標頭編號。
         */
        virtual int GetHeaderID() = 0;
        /*!
         * 設定此封包的標頭編號。
         * @param a0 此封包的標頭編號。
         */
        virtual void SetHeaderID(const int&) = 0;
        /*!
         * 設定此封包的實體資料。
         * @return 實體資料。
         */
        virtual void SetData(const std::vector<char>&) = 0;
        /*!
         * 取得此封包的資料。
         * @return 資料。
         */
        virtual std::vector<char> GetData() = 0;
        /*!
         * 取得自體封包的唯一ID。
         * @return 自體封包的唯一ID。
         * @note
         *     實作上通常是指此封包算出來的checksum或hash值。
         */
        virtual int GetSelfUniqueID() = 0;
        /*!
         * 取得指定封包的加總值。
         * @param 指定封包。
         * @return 指定封包的加總值。
         * @note
         *     實務上，使用checksum來驗證資料正確性比較有效率。
         */
        virtual char Getu8Checksum(const std::vector<char>&) = 0;
        /*!
         * 取得自體封包的加總值。
         * @return 自體封包的加總值。
         * @note
         *     實務上，使用checksum來驗證資料正確性比較有效率。
         */
        virtual char GetSelfu8Checksum() = 0;
        /*!
         * 取得指定封包的唯一ID。
         * @param 指定封包。
         * @return 指定封包的唯一ID。
         * @note
         *     實作上通常是指此封包算出來的checksum或hash值。
         */
        virtual int GetUniqueID(const std::vector<char>&) = 0;
        /*!
         * 取得整個封包資料。
         * @return 整個封包資料。
         * @note
         *     實務上常會將UniqueID附加在整個封包的最後，在這個設定下此函式傳回的整個封包資料也會包含UniqueID。
         */
        virtual std::vector<char> GetWholePacket() = 0;
        /*!
         * 匯入之無格式資料。
         * @param a0 無格式資料來源。
         * @return 使用了幾個byte。
         */
        virtual int ImportRawData(const char*) = 0;
        virtual ~IPacket() { }
	};
    struct IPacketManager:public IManager<IPacket*>
    {
        /*!
         * 創建一個封包。
         * @return 創建出來的封包。
         */
        virtual IPacket* NewPacket()=0;
        /*!
         * 由無格式資料來源創建封包。
         * @param a0 無格式資料來源。
         * @param a1 無格式資料長度。
         * @return 創建出來的封包。
         */
        virtual std::vector<IPacket*> NewPacketsWithRawData(const char*,const int&) = 0;
    };
};
extern "C"{
    igslib::IPacketManager* GetPacketManagerInstance();
};

#endif

